package com.example.horizonserver.service.impl;



import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.horizonserver.common.context.BaseContext;
import com.example.horizonserver.common.exception.DispatchBusinessException;
import com.example.horizonserver.common.exception.MaintainBusinessException;
import com.example.horizonserver.common.exception.VehicleEecption;
import com.example.horizonserver.common.result.PageResult;
import com.example.horizonserver.mapper.MaintainMapper;
import com.example.horizonserver.mapper.VehicleMapper;
import com.example.horizonserver.pojo.DTO.MaintainCompleteDTO;
import com.example.horizonserver.pojo.DTO.MaintainConfirmDTO;
import com.example.horizonserver.pojo.DTO.MaintainPageQueryDTO;
import com.example.horizonserver.pojo.DTO.MaintainSubmitDTO;
import com.example.horizonserver.pojo.VO.MaintainSubmitVO;
import com.example.horizonserver.pojo.entity.Maintain;
import com.example.horizonserver.pojo.entity.Vehicle;
import com.example.horizonserver.service.MaintainService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
@RequiredArgsConstructor
public class MaintainServiceImpl implements MaintainService {


    private final VehicleMapper vehicleMapper;

    private final MaintainMapper maintainMapper;
    /**
     * 提交保养单
     * @param maintainSubmitDTO
     * @return
     */
    @Transactional
    @Override
    @CacheEvict(cacheNames = "maintainPageCache", allEntries = true)
    public MaintainSubmitVO submitMaintain(MaintainSubmitDTO maintainSubmitDTO) {
        //只有车辆状态是可用才能提交保养单
        Vehicle vehicle = vehicleMapper.selectById(maintainSubmitDTO.getVehicleId());
        if(vehicle.getStatus() != 1)
        {
            throw new MaintainBusinessException("车辆状态不可用");
        }
        //向维护表中插入数据
        Maintain maintain = new Maintain();
        BeanUtils.copyProperties(maintainSubmitDTO,maintain);
        //补充剩余参数
        maintain.setMaintainTime(LocalDateTime.now());
        //状态设置为待维护
        maintain.setStatus(1);
        LambdaUpdateWrapper<Vehicle> luw = new LambdaUpdateWrapper<>();
        luw.eq(Vehicle::getId, maintainSubmitDTO.getVehicleId())  // 条件：id = ?
                .set(Vehicle::getStatus, 4)
                .set(Vehicle::getLastMaintainTime,LocalDateTime.now());  // 更新:status--待处理
        // lastMaintainTime--当前时间
        vehicleMapper.update(null, luw);
        //使用时间戳作为调度记录号
        maintain.setNumber(String.valueOf(System.currentTimeMillis()));
        //获取当前用户id
        Integer userId = BaseContext.getCurrentId();
        maintain.setUserId(userId);
        Integer userRole = BaseContext.getCurrentRole();
        //如果当前用户是管理员,则直接通过保修/维护,反之则等待管理员处理
        if(userRole == 1)
        {
            maintain.setStatus(2);
            luw.set(Vehicle::getStatus, 3)
                    .set(Vehicle::getLastMaintainTime,LocalDateTime.now());//将车辆状态更新为维护中
            vehicleMapper.update(null, luw);
        }
        maintainMapper.insert(maintain);
        return MaintainSubmitVO.builder()
                .id(maintain.getId())
                .maintainNumber(maintain.getNumber())
                .maintainTime(maintain.getMaintainTime())
                .build();
    }
    /**
     * 维护确认
     * @param maintainConfirmDTO
     */
    @Transactional
    @Override
    @CacheEvict(cacheNames = "maintainPageCache", allEntries = true)
    public void confirm(MaintainConfirmDTO maintainConfirmDTO) {
        //根据id查询维护记录
        Maintain maintainDB = maintainMapper.selectById(maintainConfirmDTO.getId());
        //维护记录只有存在且状态为1（待维护时）才可以通过
        if (maintainDB == null || !maintainDB.getStatus().equals(1) ){
            throw new DispatchBusinessException("维护状态不合法");
        }
        Maintain maintain = Maintain.builder()
                .id(maintainConfirmDTO.getId())
                .status(2)
                .maintainTime(LocalDateTime.now())
                .build();
        maintainMapper.updateById(maintain);
        //更新车辆状态为维护中
        Maintain maintain1 = maintainMapper.selectById(maintainConfirmDTO.getId());
        Integer vehicleId = maintain1.getVehicleId();
        LambdaUpdateWrapper<Vehicle> luw = new LambdaUpdateWrapper<>();
        luw.eq(Vehicle::getId, vehicleId)
                .set(Vehicle::getStatus, 3)
                .set(Vehicle::getLastMaintainTime,LocalDateTime.now());//更新车辆维护时间为现在
        vehicleMapper.update(null, luw);
    }

    /**
     * 维护完成 归还车辆 录入费用
     * @param maintainCompleteDTO
     */
    @Transactional
    @Override
    @CacheEvict(cacheNames = "maintainPageCache", allEntries = true)
    public void complete(MaintainCompleteDTO maintainCompleteDTO) {
        //只有状态是维护中的维护记录才可以完成维护进行归还 使车辆可用并录入维护费用
        if (!maintainMapper.selectById(maintainCompleteDTO.getId()).getStatus().equals(2)){
            throw new MaintainBusinessException("维护状态不合法");
        }
        Maintain maintain = maintainMapper.selectById(maintainCompleteDTO.getId());
        maintain.setCost(maintainCompleteDTO.getCost());
        maintain.setMaintainTime(LocalDateTime.now());
        //状态设置为维护完成
        maintain.setStatus(3);
        maintainMapper.updateById(maintain);
        //更新车辆状态为可用
        LambdaUpdateWrapper<Vehicle> luw = new LambdaUpdateWrapper<>();
        luw.eq(Vehicle::getId, maintain.getVehicleId())
                .set(Vehicle::getStatus, 1)
                .set(Vehicle::getLastMaintainTime,LocalDateTime.now());
        vehicleMapper.update(null, luw);
    }

    /**
     * 分页条件查询维护记录
     * @param maintainPageQueryDTO
     * @return
     */
    @Override
    @Cacheable(
            value = "maintainPageCache",
            key = "'page:' + #maintainPageQueryDTO.page + ':' + #maintainPageQueryDTO.pageSize",
            condition = "#maintainPageQueryDTO.pageSize==5"+
                    "&&(#maintainPageQueryDTO.status == null || #maintainPageQueryDTO.status == '') " +
                    "&& (#maintainPageQueryDTO.beginTime == null || #maintainPageQueryDTO.beginTime == '') " +
                    "&& #maintainPageQueryDTO.endTime == null || #maintainPageQueryDTO.endTime == ''"
    )
    public PageResult page(MaintainPageQueryDTO maintainPageQueryDTO) {
        if(maintainPageQueryDTO.getPage()==null||maintainPageQueryDTO.getPageSize()==null)
        {
            throw new MaintainBusinessException("未指定页数以及每页数据数");
        }
        //判断status是否符合规矩
        if(maintainPageQueryDTO.getStatus() != null && maintainPageQueryDTO.getStatus() != 1
                && maintainPageQueryDTO.getStatus() != 2&& maintainPageQueryDTO.getStatus() != 3)
        {
            throw new VehicleEecption("维护状态不合法");
        }
        // 构建分页参数
        Page<Maintain> page = new Page<>(maintainPageQueryDTO.getPage(), maintainPageQueryDTO.getPageSize());
        // 构建查询条件（使用普通 QueryWrapper 并指定表别名）
        QueryWrapper<Maintain> qw = new QueryWrapper<>();
        // 维护记录状态精确查询（假设表别名为 m，需与 Mapper.xml 中保持一致）
        qw.eq(maintainPageQueryDTO.getStatus() != null, "m.status", maintainPageQueryDTO.getStatus());
        // 时间区间记录动态查询
        qw.ge(maintainPageQueryDTO.getBeginTime() != null, "maintain_time", maintainPageQueryDTO.getBeginTime());
        qw.le(maintainPageQueryDTO.getEndTime() != null, "maintain_time", maintainPageQueryDTO.getEndTime());
        // 执行分页查询
        IPage<Maintain> maintainPage = maintainMapper.selectPageWithRelations(page, qw);
        // 封装返回结果
        PageResult pageResult = new PageResult();
        pageResult.setTotal(maintainPage.getTotal());
        pageResult.setRecords(maintainPage.getRecords());
        return pageResult;
    }


}
